//
//  ZipViewController.swift
//  JKTools
//
//  Created by 姜奎 on 2024/4/25.
//

import Cocoa

class ZipViewController: NSViewController {

    
    
    @IBOutlet weak var filePathTextField: NSTextField!
    
    @IBOutlet weak var passwordTextField: NSTextField!
    

    @IBOutlet weak var miracleAlgorithmButton: NSButton!
    
    
    @IBOutlet var descTextView: NSTextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }
    
    @IBAction func selectedFileAction(_ sender: Any) {
        NSOpenPanel.open { filePath in
            guard let filePath = filePath else {
                return
            }
            self.filePathTextField.stringValue = filePath.path
        }
        
    }
    
    @IBAction func miracleAlgorithAction(_ sender: NSButton) {
        if sender.state == .off {
            sender.state = .on
        } else {
            sender.state = .off
        }
    }
    
    @IBAction func encryptionAction(_ sender: Any) {
        
        guard filePathTextField.stringValue.isEmpty == false else {
            return
        }
        
        descTextView.string = "开始压缩，请稍后。。。"
        
        guard FileManager.default.fileExists(atPath: filePathTextField.stringValue) == true else {
            descTextView.string = descTextView.string.appending(argument: "\n请检查路径是否有效(\(filePathTextField.stringValue))")
            return
        }
        let filePath = URL(fileURLWithPath: filePathTextField.stringValue)
        
        NSSavePanel.save(name: (filePath.lastPathComponent + ".zip")) { toSavePath in
            guard let toSavePath = toSavePath else {
                return
            }
            
            zip(toPathURL: toSavePath)
        }
        
        func zip(toPathURL: URL) {
            let shell = ShellOutCommand.zip(filePathTextField.stringValue, toPathURL:toPathURL.path, password: passwordTextField.stringValue)

            do {
                try shellOut(to: shell)
                descTextView.string = descTextView.string.appending(argument: "\nZip success.")
            } catch {
                let error = error as! ShellOutError
                descTextView.string = descTextView.string.appending(argument: "\nerror:\n(\(error.message)\n\(error.output))")
            }
            
        }
        
    }
    @IBAction func decryptionAction(_ sender: Any) {
        guard filePathTextField.stringValue.isEmpty == false else {
            return
        }
        
        descTextView.string = "开始解压缩，请稍后。。。"
        
        guard FileManager.default.fileExists(atPath: filePathTextField.stringValue) == true else {
            descTextView.string = descTextView.string.appending(argument: "请检查路径是否有效(\(filePathTextField.stringValue))")
            return
        }
        
        let filePath = URL(fileURLWithPath: filePathTextField.stringValue)
        
        let lastPathComponent = filePath.deletingPathExtension().lastPathComponent
        
        NSSavePanel.save(name: lastPathComponent) { toSavePath in
            guard let toSavePath = toSavePath else {
                return
            }
            
            unzip(toPathURL: toSavePath)
        }
        
        func unzip(toPathURL: URL) {
            
            let shell = ShellOutCommand.unzip(filePathTextField.stringValue, toPathURL:toPathURL.path, password: passwordTextField.stringValue)
            do {
                try shellOut(to: shell)
                descTextView.string = descTextView.string.appending(argument: "\nUNZip success.")
            } catch {
                let error = error as! ShellOutError
                descTextView.string = descTextView.string.appending(argument: "\nerror:\n(\(error.message))\n\(error.output)")
            }
            
        }
    }
}

private extension Data {
    func shellOutput() -> String {
        guard let output = String(data: self, encoding: .utf8) else {
            return ""
        }

        guard !output.hasSuffix("\n") else {
            let endIndex = output.index(before: output.endIndex)
            return String(output[..<endIndex])
        }

        return output

    }
}
